/********************************************************************************
 * @file    bsp_gpio.h
 * @author  jianqiang.xue
 * @version V1.0.0
 * @date    2021-04-09
 * @brief   GPIO控制
 ********************************************************************************/

#ifndef __BSP_GPIO_H
#define __BSP_GPIO_H

/* Includes ------------------------------------------------------------------*/
#include <stdbool.h>
#include <stdint.h>

/* Public Enum ---------------------------------------------------------------*/
/**
 * @brief  GPIO Bit SET and Bit RESET enumeration
 */
typedef enum {
    BSP_GPIO_PIN_RESET = 0U,
    BSP_GPIO_PIN_SET
} bsp_gpio_pin_state_t;

typedef enum {
    BSP_GPIO_PIN_NOPULL = 0U,
    BSP_GPIO_PIN_PULLUP,
    BSP_GPIO_PIN_PULLDOWN
} bsp_gpio_pin_pull_t;

typedef enum {
    BSP_GPIO_PIN_OUT_OD = 0U,
    BSP_GPIO_PIN_OUT_PP,
    BSP_GPIO_PIN_AF_OD,
    BSP_GPIO_PIN_AF_PP
} bsp_gpio_pin_out_t;

typedef enum {
    BSP_GPIO_EXTI_INT_LEVEL = 0U,  // 电平触发
    BSP_GPIO_EXTI_INT_EDGE,        // 边沿触发
} bsp_gpio_exti_int_type_t;

typedef enum {
    BSP_GPIO_EXTI_INT_LOWFALL = 0U,  // 低电平触发(下降沿)
    BSP_GPIO_EXTI_INT_HIGHRISE,      // 高电平触发(上降沿)
    BSP_GPIO_EXTI_INT_FALLRISE       // 高低电平触发或任意电平变化
} bsp_gpio_exti_int_event_t;

typedef struct {
    void* port;                            // 端点号
    uint8_t pin;                           // 引脚号
    uint32_t periph;                       // GPIO外设时钟 比如 RCC_APB2PERIPH_GPIOA
    uint8_t level;                         // 电平有效状态，比如低电平点亮led，则level设置0，反之。
    uint8_t irqn;                          // 中断号 比如 EXT0_IRQn
} bsp_gpio_t;

/* Public Function Prototypes ------------------------------------------------*/

// 常规引脚初始化

void bsp_gpio_set_clk(bool aphn, uint32_t periph, bool state);
void bsp_gpio_deinit(void* gpiox, uint8_t pin);
void bsp_gpio_init_output(void* gpiox, uint8_t pin, bsp_gpio_pin_out_t out_mode);
void bsp_gpio_init_input(void* gpiox, uint8_t pin, bsp_gpio_pin_pull_t pull);
void bsp_gpio_init_input_exit(void* gpiox, uint8_t pin, uint8_t irqn, bsp_gpio_exti_int_type_t exti_type, bsp_gpio_exti_int_event_t exti_event, bsp_gpio_pin_pull_t pull);

// 外设引脚初始化

void bsp_gpio_init_adc(void* gpiox, uint8_t pin);
void bsp_gpio_init_i2c(void* gpiox, uint8_t pin, uint8_t arf);
void bsp_gpio_init_uart(void* gpiox, uint8_t pin, uint8_t arf);
void bsp_gpio_init_tim(void* gpiox, uint8_t pin, uint8_t arf);

// 引脚控制和状态获取

void bsp_gpio_set_pin(void* gpiox, uint8_t pin, bsp_gpio_pin_state_t state);
void bsp_gpio_set_toggle(void* gpiox, uint8_t pin);
bool bsp_gpio_get_state(void* gpiox, uint8_t pin);

#endif
